﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGIS.Data.Schema;

namespace NGIS
{
    namespace Model
    {
        public enum EModelEventType
		{
			EMET_RESPONSE,
			EMET_NORESPONSE,
			EMET_CONTROL
		};

		public enum EModelStateType
		{
			EMST_BASIC,
			EMST_GROUP
		};

		public enum EModelDatasetItemType
		{
			EMDIT_INTERNAL,
			EMDIT_EXTERNAL,
			EMDIT_RAW
		};

        public struct ModelParameter
        {
            public string Key;
            public string Description;
            public string DefaultValue;

            public ModelParameter(string key, string description, string defaultValue)
            {
                this.Key = key;
                this.Description = description;
                this.DefaultValue = defaultValue;
            }

            public static bool operator == (ModelParameter mpA, ModelParameter mpB)
            {
                if (mpA.Key == mpB.Key && mpA.Description == mpB.Description && mpA.DefaultValue == mpB.DefaultValue)
                {
                    return true;
                }
                return false;
            }

            public static bool operator !=(ModelParameter mpA, ModelParameter mpB)
            {
                return !(mpA != mpB);
            }
        }

		public struct ModelDatasetItem
		{
            public bool compareOther(ModelDatasetItem pDatasetItem)
			{
				if (datasetItem==null && pDatasetItem.datasetItem !=null 
					|| datasetItem !=null && pDatasetItem.datasetItem==null)
				{
					return false;
				}
				if (datasetItem!=null && pDatasetItem.datasetItem!=null)
				{
					if (datasetItem.compareOther(pDatasetItem.datasetItem)==false)
						return false;
				}
				if (datasetName != pDatasetItem.datasetName)
				{
					return false;
				}
				if (datasetItemType != pDatasetItem.datasetItemType)
				{
					return false;
				}
				if (datasetItemDescription != pDatasetItem.datasetItemDescription)
				{
					return false;
				}
				if (externalId != pDatasetItem.externalId)
				{
					return false;
				}

				return true;
			}

            public UdxDatasetSchema datasetItem;
            public string datasetName;
            public EModelDatasetItemType datasetItemType;
            public string datasetItemDescription;
            public string externalId;
		};

		public struct ModelEvent
		{
			public bool compareOther(ModelEvent pEvent)
			{
				if (eventName!=pEvent.eventName)
				{
					return false;
				}
				if (eventType != pEvent.eventType)
				{
					return false;
				}
				if (eventDescription != pEvent.eventDescription)
				{
					return false;
				}
				if (datasetReference != pEvent.datasetReference)
				{
					return false;
				}
				if (parameterDescription != pEvent.parameterDescription)
				{
					return false;
				}
				if (optional != pEvent.optional)
				{
					return false;
				}

				return true;
			}

            public string eventName;
            public EModelEventType eventType;
            public string eventDescription;
            public string datasetReference;
            public string parameterDescription;
            public bool optional;
		};

		public struct ModelState
		{
            public bool compareOther(ModelState pState)
			{
				if (stateId != pState.stateId)
				{
					return false;
				}
				if (stateName != pState.stateName)
				{
					return false;
				}
				if (stateType != pState.stateType)
				{
					return false;
				}
				if (stateDecription != pState.stateDecription)
				{
					return false;
				}
                if (modelEvents.Count != pState.modelEvents.Count)
				{
					return false;
				}
                for (int iEvent=0; iEvent < modelEvents.Count; iEvent++)
				{
					ModelEvent event1 = modelEvents[iEvent];
					ModelEvent event2 = pState.modelEvents[iEvent];
					if (event1.compareOther(event2)==false)
						return false;
				}
				return true;
			}

            public string stateId;
            public string stateName;
            public EModelStateType stateType;
            public string stateDecription;
            public List<ModelEvent> modelEvents;
		};

		public struct ModelStateTransition
		{
            public bool compareOther(ModelStateTransition pTrans)
			{
				if (fromState.compareOther(pTrans.fromState)==false)
				{
					return false;
				}
				if (toState.compareOther(pTrans.toState)==false)
				{
					return false;
				}
				return true;
			}
            public ModelState fromState;
            public ModelState toState;
		};

        public interface IModelBehavior
        {
            bool addModelDatasetItem(ref ModelDatasetItem pDataset);

            bool removeModelDatasetItem(ref ModelDatasetItem pDataset);

            int getModelDatasetItemCount();

            bool getModelDatasetItem(int idx, ref ModelDatasetItem pDataset);

            bool getModelDatasetItem(string pName, ref ModelDatasetItem pDataset);

            bool updateModelDatasetItem(int idx, ref ModelDatasetItem pDataset);

            //////////////////////////////////////Model State Group////////////////////////////////////
            bool addModelState(ref ModelState pState);

            bool removeModelState(ref ModelState pState);

            int getModelStateCount();

            bool getModelState(int idx, ref ModelState pState);

            bool getModelState(string pStateId, ref ModelState pState);

            bool updateModelState(int idx, ref ModelState pState);

            bool updateModelState(string pStateId, ref ModelState pState);

            /////////////////////////////////////Model State Transition/////////////////////////////////////
            bool addModelStateTransition(string pFromStateId, string pToStateId);

            bool addModelStateTransition(ref ModelState pFromState, ref ModelState pToState);

            bool removeModelStateTransition(string pFromStateId, string pToStateId);

            bool removeModelStateTransition(ref ModelState pFromState, ref ModelState pToState);

            int getModelStateTransitionCount();

            bool getModelStateTransition(int idx, ref ModelState pFromState, ref ModelState pToState);

            bool getModelStateTransition(int idx, ref ModelStateTransition pStateTransition);

            bool existModelStatetTransition(string pFromStateId, string pToStateId);

            bool existModelStatetTransition(ref ModelState pFromState, ref ModelState pToState);

            bool updateModelStateTransition(int idx, string pFromStateId, string pToStateId);

            ///////////////////////////////////Parameters///////////////////////////////////////
            bool addProcessParameter(ModelParameter processparameter);

            bool getProcessParameter(string key, ref ModelParameter parameter);

            int getProcessParameterCount();

            bool removeProcessParameter(ModelParameter processparameter);

            bool updateProcessParameter(ModelParameter processparameter);

            bool addControlParameter(ModelParameter processparameter);

            bool getControlParameter(string key, ref ModelParameter parameter);

            int getControlParameterCount();

            bool removeControlParameter(ModelParameter controlparameter);

            bool updateControlParameter(ModelParameter controlparameter);

            //////////////////////////////////////////////////////////////////////////
            bool compareOther(IModelBehavior pBehavior, ref string obj, ref string name);
        }
    }
}